#include "WineryList.h"

WineryList::WineryList(){}

/**********************************************************************
 * initializeListFromFile()
 *
 * creates a vector from the .txt file that can be used by the program
 * and written to the binary file
 *
 * Preconditions: .txt file must exist
 * PostConditions: WineryList vector created
 **********************************************************************/
void WineryList::initializeListFromFile()
{
	fstream inFile;
	string name;
	int wNum, cWineries;
	float distFromCV;
	int numOfWines;
	fstream binFile;

	inFile.open("wineries.txt", ios::in);

	//load vector from .txt file
	while (inFile)
	{
		distFromHere allDistances;
		wines stockList;		//WineryList Object for creating list

		//INPUT - Gets newWinery Information and then loads to vector
		getline(inFile, name);
		inFile >> wNum >> cWineries;

		//Loop # of times of total wineries to get distance from other
		//Wineries information
		for(int i = 0; i < cWineries; i++)
		{
			int wNum;
			float distance;

			inFile >> wNum >> distance;
			Distances newDistance(wNum, distance);	//Distance Struct
			//Load Distance struct to Distance Vector
			allDistances.push_back(newDistance);
		}
		inFile >> distFromCV;
		inFile >> numOfWines;

		//loop # of total wines and load to vector
		for(int j = 0; j < numOfWines; j++)
		{
			string wName;
			int vintage;
			float price;

			inFile.ignore();
			getline(inFile,wName);
			inFile >> vintage >> price;
			WineInfo stockItem(wName, vintage, price);
			stockList.push_back(stockItem);
		}

		//Instantiate newWinery Class Object and pushing onto WineList vector
		Winery newWinery(name, wNum, allDistances,distFromCV, numOfWines, stockList);
		WineList.push_back(newWinery);
		Winery::totalWineries++;
		inFile.ignore();
	}
	WineList.pop_back(); //Removes last empty node from list
	Winery::totalWineries--;//and decrements total wineries accordingly

	//create bin file
//	UpdateBinFile(WineList);

	inFile.close();
}

//Adds a new winery to the list
void WineryList::addNewWinery(Winery newWinery)
{
	WineList.push_back(newWinery);
	//Increment total wineries
	Winery::totalWineries++;
}

//Deletes a winery from the list
void WineryList::deleteWinery(int key)
{
	key -= 1;
	WineList.erase(WineList.begin()+ key);
	Winery::totalWineries--;
}


vector<Winery> WineryList::getList(){return WineList;}

//Sorts WineryList in order of Closest to Canyon Villa
void WineryList::sortList(){sort(WineList.begin(), WineList.end());}

vector <Winery>::iterator WineryList::SearchList(int srchValue)
{
	vector <Winery>::iterator found;
	found = find(WineList.begin(), WineList.end(),srchValue);
	return found;
}

void WineryList::printList()
{
	//Prints basic List of Wineries
	for(p = WineList.begin(); p < WineList.end(); p++)
	{
		cout << setw(5) << left << p->getWineryNumber();
		cout << setw(25) << p->getWineryName() << endl;
		p->PrintWines();
	}
	cout << endl << endl;
	//Needs to be formatted to look nice and more readable
}

//CONVERTS CLASS OBJECTS TO A DATA STRUCT THAT CONTAINS ONLY NECESSARY
//INFORMATION. (CONVERTS STRINGS TO C_STR() FOR BINARY READ/WRITE)
WineryData WineryList::createDataFromWinery(Winery& object)
{
	WineryData data;
	wines temp;
	wines::iterator t;

	//CONVERTING STRING TO C_STR()
	for(int i = 0; i < 200; i++)
	{
		data.wineryName[i] = 0;
	}
	strncpy(data.wineryName, object.getWineryName().c_str(),100);
	data.wineryName[99] = 0;
	//FILLING REMAINING VALUES
	data.wineryNumber = object.getWineryNumber();
	data.current = object.getDistances();
	data.fromCanyonVilla = object.getDistanceFromCV();
	data.numberOfWines = object.getNumberOfWines();
	temp = object.getStock();
	t = temp.begin();
	for(int i = 0; i < data.numberOfWines; i++)
	{
		winesData thisWine;
		//CONVERTING STRING TO C_STR()
		strncpy(thisWine.wineName,t->getWineName().c_str(),100);
		thisWine.wineName[99] = 0;
		//FILLING REMAINING VALUES
		thisWine.vintage = t->getVintage();
		thisWine.price = t->getPrice();
		data.wList.push_back(thisWine);
	}
	return data;
}
//CREATES WINERY CLASS OBJECT FROM BINARY FILE INFORMATION
Winery WineryList::createWineryFromData(WineryData& data)
{
	wines newList;
	for(data.wd = data.wList.begin();data.wd < data.wList.end(); data.wd++)
	{
		WineInfo thisWine(data.wd->wineName,data.wd->vintage,data.wd->price);
		newList.push_back(thisWine);
	}
	Winery fromData(data.wineryName, data.wineryNumber, data.current,
			data.fromCanyonVilla, data.numberOfWines, newList);
	return fromData;
}

//WRITES WINERYLIST TO BINARY FILE
bool WineryList::writeToBinary(string fileName)
{
	fstream boutFile;	//file-stream for binary output
	int n; 				//size for output
	Winery currentWinery;
	WineryData currentData;
	boutFile.open(fileName.c_str(), ios::out | ios::binary | ios::trunc);
	n = Winery::totalWineries;
	p = WineList.begin();
	for (p = WineList.begin(); p < WineList.end(); p++)
	{
		currentWinery = *p;
		currentData = createDataFromWinery(currentWinery);
		boutFile.write((char*)&currentData, sizeof(WineryData));
	}
	boutFile.close();
	return true;
}

//READS FROM BINARY FILE AND CREATES WINERYLIST
vector <Winery> WineryList::initListfromData(string fileName)
{
	ifstream binFile;
	Winery newWinery;
	WineryData wData;
	binFile.open(fileName.c_str(), ios::in | ios::binary);

	for(int i = 0; i < 30; i++)
	{

		if(binFile.eof())
			break;
		binFile.read((char*)&wData, sizeof(WineryData));
		newWinery = createWineryFromData(wData);
		WineList.push_back(newWinery);
	}
	WineList.pop_back();
	cout << newWinery.getCount() << endl << endl;
	binFile.close();
	return WineList;
}
